package main

import (
	"encoding/json"
	"fmt"
	"reflect"
)

// 结构体标签 定义一些属性额外的信息
type resume struct {
	Name string `info:"name" doc:"我的名字"`
	Sex  string `info:"sex"`
}

// 结构体标签可以用来做json库的提示  类似于java的注解
type Movie struct {
	Title  string   `json:"title"`
	Year   int      `json:"year"`
	Actors []string `json:"actors"`
}

func findTag(arg interface{}) {
	t := reflect.TypeOf(arg)
	for i := 0; i < t.NumField(); i++ {
		info := t.Field(i).Tag.Get("info")
		doc := t.Field(i).Tag.Get("doc")
		fmt.Println(info, doc)
	}
}

func findTagByPoint(arg interface{}) {
	// 指针类型的反射 需要加.Elem()取实际指向的类
	t := reflect.TypeOf(arg).Elem()
	for i := 0; i < t.NumField(); i++ {
		info := t.Field(i).Tag.Get("info")
		doc := t.Field(i).Tag.Get("doc")
		fmt.Println(info, doc)
	}
}

func main14() {
	var r resume
	findTag(r)
	findTagByPoint(&r)

	movie := Movie{"喜剧之王", 2000, []string{"周星驰", "张柏芝"}}
	jsonStr, err := json.Marshal(movie)
	if err != nil {
		return
	}
	// 会按照struct中的提示序列化
	fmt.Printf("%s\n", jsonStr)

	newMovie := Movie{}
	err = json.Unmarshal(jsonStr, &newMovie)
	if err != nil {
		fmt.Println("unmarshal error")
		return
	}
	fmt.Println(newMovie)
}
